// This form is just our window.  It does a few things
//  
//  Initialization
//  Gets the versions from unicode CLDR
//  Changes versions if changed
//  Filters the locales if necessary
//  Triggers the import
//  Import loops through all the selected locales and makes CldrLocale import its data.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Globalization;

namespace customcldr
{
    public partial class MainForm : Form
    {
        Download dlForm = null;
        ArrayList currentversions = null;
        String[] strFiles = null;
        CldrLocaleList cultures = null;

        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            LoadMergeLists();
        }

        private void GetVersions()
        {
            this.dlForm = new Download(URLTextBox.Text, this);
            this.dlForm.GetVersions();
        }

        internal void SetVersions(ArrayList versions)
        {
            this.currentversions = versions;
            this.versions.Items.Clear();

            int i;
            for (i = 0; i < this.currentversions.Count; i++)
            {
                CldrVersionInfo ver = (CldrVersionInfo)this.currentversions[i];
                this.versions.Items.Add(ver.Label);
            }
            if (i > 0)
            {
                // BUG: Right now its picking the wrong one because of the order.
                this.versions.SetSelected(i - 2, true);
               // SetVersion(i - 1);
            }
        }

        private void versions_SelectedIndexChanged(object sender, EventArgs e)
        {
            SetVersion(this.versions.SelectedIndex);
        }

        private void SetVersion(int i)
        {
            CldrVersionInfo ver = (CldrVersionInfo)this.currentversions[i];
            if (ver != null) this.dlForm.SetVersion(ver);
        }

        private void URLTextBox_TextChanged(object sender, EventArgs e)
        {
            GetVersions();
        }

        internal void ChangeLoading(string label)
        {
            Loading.Text = label;
        }

        private void MainForm_Activated(object sender, EventArgs e)
        {
            if (dlForm == null) GetVersions();
        }

        private void systemLocales_CheckedChanged(object sender, EventArgs e)
        {
            RefreshCultureList();
        }

        private void existingLocales_CheckedChanged(object sender, EventArgs e)
        {
            RefreshCultureList();
        }

        private void uiLanguage_TextChanged(object sender, EventArgs e)
        {
            LoadCultureList();
            RefreshCultureList();
        }

        internal void SetCldrFiles(String[] strFiles)
        {
            this.strFiles = strFiles;
            LoadCultureList();
            RefreshCultureList();
        }

        internal void RefreshCultureList()
        {
            this.Locales.Items.Clear();

            for (int i = 0; i < cultures.Count; i++)
            {
                CldrLocale loc = (CldrLocale) cultures[i];
                if ((loc.IsSystemLocale == false || this.systemLocales.Checked == true) &&
                    (loc.IsInstalledLocale == false || this.existingLocales.Checked == true) &&
                    (loc.IsNeutralLocale == false || this.allowNeutrals.Checked == true))
                {
                    if (loc.IsRoot == false)
                    {
                        this.Locales.Items.Add(loc);
                        Console.WriteLine(loc.ToString());
                    }
                }
            }

            this.cntLoc.Text = "Locales: " + this.Locales.Items.Count;
            this.cntsel.Text = "Selected: 0";

        }

        internal void LoadCultureList()
        {
            this.cultures = new CldrLocaleList(this.uiLanguage.Text);
            for (int i = 0; i < this.strFiles.Length; i++)
            {
                String temp = strFiles[i];
                int j = temp.LastIndexOf('\\');
                if (j > 0) temp = temp.Substring(j + 1);
//                if (temp == "root.xml") continue;
                CldrLocale loc = new CldrLocale(strFiles[i], temp);
                this.cultures.Add(loc);
            }
        }

        // This imports them all.  (By making CldrLocale import them)
        private void Import_Click(object sender, EventArgs e)
        {
            String temp = "Do you want to import these " + Locales.SelectedIndices.Count + " locales?";
            if (MessageBox.Show(temp, "Are You Sure?",
                MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation) != DialogResult.OK)
                return;

            int worked = 0;
            int failed = 0;

            // We need parents first, so start with least # of dashes.
            // worst case is lang-sublang-script-region-variant (4 dashes)
            for (int dashes = 0; dashes < 5; dashes++)
            {
                IEnumerator index = this.Locales.SelectedIndices.GetEnumerator();
                while (index.MoveNext())
                {
                    try
                    {
                        // We have to do parent neutral locales before the others
                        // otherwise setting the parent fails.  Luckily they are in order.
                        CldrLocale loc = (CldrLocale)this.Locales.Items[(int)index.Current];

                        if (dashes == loc.Dashes())
                        {
                            loc.Register();
                            worked++;
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.ToString());
                        failed++;
                    }
                }
            }

            CultureInfo.InvariantCulture.ClearCachedData();
            MessageBox.Show(worked.ToString() + " locales were imported", "Task Complete",
                            MessageBoxButtons.OK, MessageBoxIcon.Information);

            if (failed > 0)
            {
                MessageBox.Show(failed.ToString() + " locales failed", "Task Not Complete",
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            LoadCultureList();
            RefreshCultureList();
        }

        private void Locales_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.cntsel.Text = "Selected: " + Locales.SelectedIndices.Count;
        }

        private void allowNeutrals_CheckedChanged(object sender, EventArgs e)
        {
            RefreshCultureList();
        }

        private void HelpLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            // BUG: Fix this to go to a help file. (just help.txt I guess)
            System.Diagnostics.Process.Start("help.txt");
        }

        private void MergeLanguageList_SelectedIndexChanged(object sender, EventArgs e)
        {
            FixMergeLocaleName();
        }

        private void MergeRegionList_SelectedIndexChanged(object sender, EventArgs e)
        {
            FixMergeLocaleName();
        }

        private void FixMergeLocaleName()
        {
            CultureInfo language = (CultureInfo)this.MergeLanguageList.SelectedItem;
            CultureInfo region = (CultureInfo)this.MergeRegionList.SelectedItem;

            string strName;
            int i;

            if (language != null && region != null)
            {
                strName = language.Name;
                i = strName.LastIndexOf('-');
                if (i > 0)
                {
                    strName = strName.Substring(0, i);
                }
                i = region.Name.LastIndexOf('-');
                if (i > 0)
                {
                    strName = strName + region.Name.Substring(i);
                }

                this.MergeResult.Text = strName;
            }

            if (region != null)
            {
                RegionInfo ri = new RegionInfo(region.Name);

                // Try to fix the english and native names
                this.MergeEnglishRegion.Text = ri.EnglishName;
                this.MergeNativeRegion.Text = "???";

                // Try to fix the culture names
                strName = language.NativeName;
                i = strName.IndexOf('(');
                if (i > 0)
                {
                    strName = strName.Substring(0, i);
                }
                else
                {
                    strName += " ";
                }
                this.MergeNativeName.Text = strName + "(" + this.MergeNativeRegion.Text + ")";
                if (language.TwoLetterISOLanguageName == "en")
                {
                    this.MergeNativeRegion.Text = this.MergeEnglishRegion.Text;
                    this.MergeNativeName.Text = this.MergeEnglishName.Text;
                }


                strName = language.EnglishName;
                i = strName.IndexOf('(');
                if (i > 0)
                {
                    strName = strName.Substring(0, i);
                }
                else
                {
                    strName += " ";
                }
                this.MergeEnglishName.Text = strName + "(" + this.MergeEnglishRegion.Text + ")";
            }
            else
            {
            }
        }

        private void LoadMergeLists()
        {
            this.MergeLanguageList.Items.Clear();
            this.MergeRegionList.Items.Clear();

            CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.SpecificCultures);

            for (int i = 0; i < cultures.Length; i++)
            {
                this.MergeLanguageList.Items.Add(cultures[i]);
                this.MergeRegionList.Items.Add(cultures[i]);
            }

            this.MergeResult.Text = "";
        }

        private void Merge_Click(object sender, EventArgs e)
        {
            // This is a really lazy way of doing this
            CultureInfo language = (CultureInfo)this.MergeLanguageList.SelectedItem;
            RegionInfo region = new RegionInfo(((CultureInfo)
                this.MergeRegionList.SelectedItem).Name);

            try
            {
                if (CultureInfo.GetCultureInfo(this.MergeResult.Text) != null)
                {
                    MessageBox.Show(this.MergeResult.Text + " already registered",
                                    "Unable to Merge",
                                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }
            catch (ArgumentException)
            {
            }

            // Get the defaults
            CultureAndRegionInfoBuilder carib = new CultureAndRegionInfoBuilder(
                this.MergeResult.Text, CultureAndRegionModifiers.None);
            carib.LoadDataFromCultureInfo(language);
            carib.LoadDataFromRegionInfo(region);
            
            // Need to fix the display names, this most likely doesn't work right.
            carib.CultureEnglishName = this.MergeEnglishName.Text;
            carib.CultureNativeName = this.MergeNativeName.Text;
            
            carib.RegionEnglishName = this.MergeEnglishRegion.Text;
            carib.RegionNativeName = this.MergeNativeRegion.Text;

            // Make sure our names were updated
            if (carib.RegionNativeName == "???" ||
                carib.CultureNativeName.IndexOf("???") > 0)
            {
                MessageBox.Show("Native names need filled in before merging",
                                "Unable to Merge",
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            carib.Register();
        
            // Reload the lists
            LoadMergeLists();
        }
    }
}
